//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.mass.core.activiti.workflow.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mass.core.activiti.workflow.cmd.JumpActivityCmd;
import com.mass.core.activiti.workflow.model.ProcessListVo;
import com.mass.core.activiti.workflow.service.WorkflowProcessDefinitionService;
import com.mass.core.activiti.workflow.service.WorkflowTraceService;
import com.mass.core.utils.AjaxResponse;
import com.mass.core.utils.WorkflowUtils;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;

import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.ManagementService;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@RestController
@RequestMapping({"/activiti/workflow"})
public class ActivitiController {
    protected Logger logger = LoggerFactory.getLogger(this.getClass());
    protected WorkflowProcessDefinitionService workflowProcessDefinitionService;
    protected RepositoryService repositoryService;
    protected RuntimeService runtimeService;
    protected TaskService taskService;
    protected WorkflowTraceService traceService;
    @Autowired
    ManagementService managementService;
    protected static Map<String, ProcessDefinition> PROCESS_DEFINITION_CACHE = new HashMap<String, ProcessDefinition>();
    @Autowired
    ProcessEngineFactoryBean processEngine;
    @Autowired
    ProcessEngineConfiguration processEngineConfiguration;
    @Value("${export.diagram.path}")
    private String exportDiagramPath;

    public ActivitiController() {
    }

    @RequestMapping({"/process-list"})
    public AjaxResponse processList(@RequestParam("page") Integer pageIndex, @RequestParam("limit") Integer pageSize) {
		ArrayList<ProcessListVo> objects = new ArrayList<ProcessListVo>();
        pageIndex = Integer.valueOf(pageIndex == null?1:pageIndex.intValue());
        pageSize = Integer.valueOf(pageSize == null?10:pageSize.intValue());
        ProcessDefinitionQuery processDefinitionQuery = (ProcessDefinitionQuery)this.repositoryService.createProcessDefinitionQuery().orderByDeploymentId().desc();
        List<ProcessDefinition> processDefinitionList = processDefinitionQuery.listPage((pageIndex-1)*pageSize, pageSize);
        Iterator<ProcessDefinition> var8 = processDefinitionList.iterator();

        while(var8.hasNext()) {
            ProcessDefinition page = (ProcessDefinition)var8.next();
            String deploymentId = page.getDeploymentId();
            Deployment deployment = (Deployment)this.repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
            ProcessListVo tempVo = new ProcessListVo();
            tempVo.setId(page.getId());
            tempVo.setDeploymentId(page.getDeploymentId());
            tempVo.setName(page.getName());
            tempVo.setKey(page.getKey());
            tempVo.setVersion(Integer.valueOf(page.getVersion()));
            tempVo.setResourceName(page.getResourceName());
            tempVo.setDiagramResourceName(page.getDiagramResourceName());
            tempVo.setDeploymentTime(deployment.getDeploymentTime());
            tempVo.setSuspended(page.isSuspended());
            objects.add(tempVo);
        }
        return AjaxResponse.success("ok", objects, processDefinitionQuery.count(), pageIndex.intValue());
    }

    @RequestMapping({"/redeploy/all"})
    public AjaxResponse redeployAll() throws Exception {
        this.workflowProcessDefinitionService.deployAllFromClasspath(this.exportDiagramPath);
        return AjaxResponse.success("ok");
    }

    @RequestMapping({"/resource/read"})
    public void loadByDeployment(@RequestParam("processDefinitionId") String processDefinitionId, @RequestParam("resourceType") String resourceType, HttpServletResponse response) throws Exception {
        response.setCharacterEncoding("UTF-8");
        ProcessDefinition processDefinition = (ProcessDefinition)this.repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
        String resourceName = "";
        if(resourceType.equals("image")) {
            resourceName = processDefinition.getDiagramResourceName();
            response.setHeader("Content-Type", "image/jpg");
        } else if(resourceType.equals("xml")) {
            response.setHeader("Content-Type", "text/xml");
            resourceName = processDefinition.getResourceName();
        }

        InputStream resourceAsStream = this.repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
        byte[] b = new byte[1024];
        @SuppressWarnings("unused")
		boolean len = true;

        int len1;
        while((len1 = resourceAsStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len1);
        }

    }

    @RequestMapping({"/resource/process-instance"})
    public void loadByProcessInstance(@RequestParam("type") String resourceType, @RequestParam("pid") String processInstanceId, HttpServletResponse response) throws Exception {
        InputStream resourceAsStream = null;
        ProcessInstance processInstance = (ProcessInstance)this.runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        ProcessDefinition processDefinition = (ProcessDefinition)this.repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId()).singleResult();
        String resourceName = "";
        if(resourceType.equals("image")) {
            resourceName = processDefinition.getDiagramResourceName();
        } else if(resourceType.equals("xml")) {
            resourceName = processDefinition.getResourceName();
        }

        resourceAsStream = this.repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
        byte[] b = new byte[1024];
        @SuppressWarnings("unused")
		boolean len = true;

        int len1;
        while((len1 = resourceAsStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len1);
        }

    }

    @RequestMapping({"/process/delete"})
    public AjaxResponse delete(@RequestParam("deploymentId") String deploymentId) {
        this.repositoryService.deleteDeployment(deploymentId, true);
        return AjaxResponse.success("ok");
    }

    @RequestMapping({"/process/trace"})
    @ResponseBody
    public List<Map<String, Object>> traceProcess(@RequestParam("pid") String processInstanceId) throws Exception {
        List<Map<String, Object>> activityInfos = this.traceService.traceProcess(processInstanceId);
        return activityInfos;
    }

    @RequestMapping({"/process/trace/auto/{executionId}"})
    public void readResource(@PathVariable("executionId") String executionId, HttpServletResponse response) throws Exception {
        ProcessInstance processInstance = (ProcessInstance)this.runtimeService.createProcessInstanceQuery().processInstanceId(executionId).singleResult();
        BpmnModel bpmnModel = this.repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
        List<String> activeActivityIds = this.runtimeService.getActiveActivityIds(executionId);
        this.processEngineConfiguration = this.processEngine.getProcessEngineConfiguration();
        Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl)this.processEngineConfiguration);
        ProcessDiagramGenerator diagramGenerator = this.processEngineConfiguration.getProcessDiagramGenerator();
        InputStream imageStream = diagramGenerator.generateDiagram(bpmnModel, "png", activeActivityIds);
        byte[] b = new byte[1024];

        int len;
        while((len = imageStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }

    }

    @RequestMapping({"/deploy"})
    public AjaxResponse deploy(@RequestParam(value = "file",required = false) MultipartFile file) {
        String fileName = file.getOriginalFilename();

        try {
            InputStream e = file.getInputStream();
            Deployment deployment = null;
            String extension = FilenameUtils.getExtension(fileName);
            if(!extension.equals("zip") && !extension.equals("bar")) {
                deployment = this.repositoryService.createDeployment().addInputStream(fileName, e).deploy();
            } else {
                ZipInputStream list = new ZipInputStream(e);
                deployment = this.repositoryService.createDeployment().addZipInputStream(list).deploy();
            }

            List<?> list1 = this.repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).list();
            Iterator<?> var8 = list1.iterator();

            while(var8.hasNext()) {
                ProcessDefinition processDefinition = (ProcessDefinition)var8.next();
                WorkflowUtils.exportDiagramToFile(this.repositoryService, processDefinition, this.exportDiagramPath);
            }
        } catch (Exception var9) {
            this.logger.error("error on deploy process, because of file input stream", var9);
        }

        return AjaxResponse.success("ok");
    }

    @RequestMapping({"/process/convert-to-model/{processDefinitionId}"})
    public AjaxResponse convertToModel(@PathVariable("processDefinitionId") String processDefinitionId) throws UnsupportedEncodingException, XMLStreamException {
        ProcessDefinition processDefinition = (ProcessDefinition)this.repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
        InputStream bpmnStream = this.repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
        XMLInputFactory xif = XMLInputFactory.newInstance();
        InputStreamReader in = new InputStreamReader(bpmnStream, "UTF-8");
        XMLStreamReader xtr = xif.createXMLStreamReader(in);
        BpmnModel bpmnModel = (new BpmnXMLConverter()).convertToBpmnModel(xtr);
        BpmnJsonConverter converter = new BpmnJsonConverter();
        ObjectNode modelNode = converter.convertToJson(bpmnModel);
        Model modelData = this.repositoryService.newModel();
        modelData.setKey(processDefinition.getKey());
        modelData.setName(processDefinition.getResourceName());
        modelData.setCategory(processDefinition.getDeploymentId());
        ObjectNode modelObjectNode = (new ObjectMapper()).createObjectNode();
        modelObjectNode.put("name", processDefinition.getName());
        modelObjectNode.put("revision", 1);
        modelObjectNode.put("description", processDefinition.getDescription());
        modelData.setMetaInfo(modelObjectNode.toString());
        this.repositoryService.saveModel(modelData);
        this.repositoryService.addModelEditorSource(modelData.getId(), modelNode.toString().getBytes("utf-8"));
        return AjaxResponse.success("ok");
    }

    @RequestMapping({"/task/todo/list"})
    @ResponseBody
    public List<Map<String, Object>> todoList(HttpSession session) throws Exception {
        /*SysUser user = (SysUser)WebHelper.getSessionAttribute(session, "sessionLoginUser", SysUser.class);*/
        ArrayList<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        List<?> todoList = null; //((TaskQuery)this.taskService.createTaskQuery().taskAssignee(user.getAccount())).active().list();
        @SuppressWarnings("null")
		Iterator<?> task = todoList.iterator();

        while(task.hasNext()) {
            Task toClaimList = (Task)task.next();
            String processDefinitionId = toClaimList.getProcessDefinitionId();
            ProcessDefinition processDefinitionId1 = this.getProcessDefinition(processDefinitionId);
            Map<String, Object> processDefinition = this.packageTaskInfo(sdf, toClaimList, processDefinitionId1);
            processDefinition.put("status", "todo");
            result.add(processDefinition);
        }

        List<?> toClaimList1 = ((TaskQuery)this.taskService.createTaskQuery().taskCandidateGroup("deptGroup")).active().list();
        Iterator<?> processDefinitionId2 = toClaimList1.iterator();

        while(processDefinitionId2.hasNext()) {
            Task task1 = (Task)processDefinitionId2.next();
            String processDefinitionId3 = task1.getProcessDefinitionId();
            ProcessDefinition processDefinition1 = this.getProcessDefinition(processDefinitionId3);
            Map<String, Object> singleTask = this.packageTaskInfo(sdf, task1, processDefinition1);
            singleTask.put("status", "claim");
            result.add(singleTask);
        }

        return result;
    }

    private Map<String, Object> packageTaskInfo(SimpleDateFormat sdf, Task task, ProcessDefinition processDefinition) {
        HashMap<String, Object> singleTask = new HashMap<String, Object>();
        singleTask.put("id", task.getId());
        singleTask.put("name", task.getName());
        singleTask.put("createTime", sdf.format(task.getCreateTime()));
        singleTask.put("pdname", processDefinition.getName());
        singleTask.put("pdversion", Integer.valueOf(processDefinition.getVersion()));
        singleTask.put("pid", task.getProcessInstanceId());
        return singleTask;
    }

    private ProcessDefinition getProcessDefinition(String processDefinitionId) {
        ProcessDefinition processDefinition = (ProcessDefinition)PROCESS_DEFINITION_CACHE.get(processDefinitionId);
        if(processDefinition == null) {
            processDefinition = (ProcessDefinition)this.repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
            PROCESS_DEFINITION_CACHE.put(processDefinitionId, processDefinition);
        }

        return processDefinition;
    }

    @RequestMapping({"processdefinition/update/{state}/{processDefinitionId}"})
    public AjaxResponse updateState(@PathVariable("state") String state, @PathVariable("processDefinitionId") String processDefinitionId, RedirectAttributes redirectAttributes) {
        if(state.equals("active")) {
            redirectAttributes.addFlashAttribute("message", "已激活ID为[" + processDefinitionId + "]的流程定义。");
            this.repositoryService.activateProcessDefinitionById(processDefinitionId, true, (Date)null);
        } else if(state.equals("suspend")) {
            this.repositoryService.suspendProcessDefinitionById(processDefinitionId, true, (Date)null);
            redirectAttributes.addFlashAttribute("message", "已挂起ID为[" + processDefinitionId + "]的流程定义。");
        }

        return AjaxResponse.success("ok");
    }

    @RequestMapping({"export/diagrams"})
    @ResponseBody
    public List<String> exportDiagrams(@Value("#{APP_PROPERTIES[\'export.diagram.path\']}") String exportDir) throws IOException {
        ArrayList<String> files = new ArrayList<String>();
        List<?> list = this.repositoryService.createProcessDefinitionQuery().list();
        Iterator<?> var5 = list.iterator();

        while(var5.hasNext()) {
            ProcessDefinition processDefinition = (ProcessDefinition)var5.next();
            files.add(WorkflowUtils.exportDiagramToFile(this.repositoryService, processDefinition, exportDir));
        }

        return files;
    }

    @RequestMapping({"activity/jump"})
    @ResponseBody
    public boolean jump(@RequestParam("executionId") String executionId, @RequestParam("activityId") String activityId) {
        JumpActivityCmd cmd = new JumpActivityCmd(executionId, activityId);
        this.managementService.executeCommand(cmd);
        return true;
    }

    @RequestMapping({"bpmn/model/{processDefinitionId}"})
    @ResponseBody
    public BpmnModel queryBpmnModel(@PathVariable("processDefinitionId") String processDefinitionId) {
        BpmnModel bpmnModel = this.repositoryService.getBpmnModel(processDefinitionId);
        return bpmnModel;
    }

    @Autowired
    public void setWorkflowProcessDefinitionService(WorkflowProcessDefinitionService workflowProcessDefinitionService) {
        this.workflowProcessDefinitionService = workflowProcessDefinitionService;
    }

    @Autowired
    public void setRepositoryService(RepositoryService repositoryService) {
        this.repositoryService = repositoryService;
    }

    @Autowired
    public void setRuntimeService(RuntimeService runtimeService) {
        this.runtimeService = runtimeService;
    }

    @Autowired
    public void setTraceService(WorkflowTraceService traceService) {
        this.traceService = traceService;
    }

    @Autowired
    public void setTaskService(TaskService taskService) {
        this.taskService = taskService;
    }
}
